package com.czc.datamask.aop;

import com.czc.datamask.annotation.Dataprocess;
import com.czc.datamask.util.AseUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
<<<<<<< HEAD
import java.util.List;
=======
>>>>>>> 396012d7fd163870bb0b2280da664f01118a4cbc
import java.util.Objects;


@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
@Aspect
public class DataProcessAspect {
    Logger log = LoggerFactory.getLogger(this.getClass());

    @Value("${secretKey}")
    private String secretKey;

    @Pointcut("@annotation(com.czc.datamask.annotation.MethodProcess)")
    public void annotationPointCut() {
    }

    @Around("annotationPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) {
        Object responseObj = null;
        try {
                if (joinPoint.getArgs().length != 0) {  //请求参数不为空的情况下
                    Object requestObj = joinPoint.getArgs()[0];
                    handleEncrypt(requestObj);
                }
                    responseObj = joinPoint.proceed();
                    handleDecrypt(responseObj);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            log.error("Aop自动加解密处理出现异常{}", e);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            log.error("Aop自动加解密处理出现异常{}", throwable);
        }
        return responseObj;
    }

    /**
     * 处理加密
     *
     * @param requestObj
     */
    private void handleEncrypt(Object requestObj) throws IllegalAccessException {
        if (Objects.isNull(requestObj)) {
            return;
        }
<<<<<<< HEAD
        if (requestObj instanceof List) {
            List<Object> requestList = (List<Object>) requestObj;
            for (Object obj : requestList) {
                encryptFields(obj);
            }
        } else {
            encryptFields(requestObj);
        }
    }

    private void encryptFields(Object obj) throws IllegalAccessException {
        Field[] fields = obj.getClass().getDeclaredFields();
=======
        Field[] fields = requestObj.getClass().getDeclaredFields();
>>>>>>> 396012d7fd163870bb0b2280da664f01118a4cbc
        for (Field field : fields) {
            boolean hasSecureField = field.isAnnotationPresent(Dataprocess.class);
            if (hasSecureField) {
                field.setAccessible(true);
<<<<<<< HEAD
                String plaintextValue = (String) field.get(obj);
                String encryptValue = AseUtil.encrypt(plaintextValue, secretKey);
                field.set(obj, encryptValue);
=======
                String plaintextValue = (String) field.get(requestObj);
                String encryptValue = AseUtil.encrypt(plaintextValue, secretKey);
                field.set(requestObj, encryptValue);
>>>>>>> 396012d7fd163870bb0b2280da664f01118a4cbc
            }
        }
    }


<<<<<<< HEAD
=======
    /**
     * 处理解密
     *
     * @param responseObj
     */
>>>>>>> 396012d7fd163870bb0b2280da664f01118a4cbc
    private Object handleDecrypt(Object responseObj) throws IllegalAccessException {
        if (Objects.isNull(responseObj)) {
            return null;
        }
<<<<<<< HEAD
        if (responseObj instanceof List) {
            List<Object> responseList = (List<Object>) responseObj;
            for (Object obj : responseList) {
                decryptFields(obj);
            }
        } else {
            decryptFields(responseObj);
        }
        return responseObj;
    }

    private void decryptFields(Object obj) throws IllegalAccessException {
        Field[] fields = obj.getClass().getDeclaredFields();
=======
        Field[] fields = responseObj.getClass().getDeclaredFields();
>>>>>>> 396012d7fd163870bb0b2280da664f01118a4cbc
        for (Field field : fields) {
            boolean hasSecureField = field.isAnnotationPresent(Dataprocess.class);
            if (hasSecureField) {
                field.setAccessible(true);
<<<<<<< HEAD
                String encryptValue = (String) field.get(obj);
                String plaintextValue = AseUtil.decrypt(encryptValue, secretKey);
                field.set(obj, plaintextValue);
            }
        }
=======
                String encryptValue = (String) field.get(responseObj);
                String plaintextValue = AseUtil.decrypt(encryptValue, secretKey);
                field.set(responseObj, plaintextValue);
            }
        }
        return responseObj;
>>>>>>> 396012d7fd163870bb0b2280da664f01118a4cbc
    }
}
